import 'dart:convert';

import 'package:dio/dio.dart';
import 'package:pretty_dio_logger/pretty_dio_logger.dart';
import 'package:sp_util/sp_util.dart';

import '../api.dart';
import 'base_resp.dart';

enum AppMethod { GET, POST, DELETE, PUT }

/// 成功识别status
const int successCode = 1;

/// token 过期
const int tokenFailureCode = 2;

///使用：AppMethodValues[AppMethod.POST]
const AppMethodValues = {
  AppMethod.GET: "get",
  AppMethod.POST: "post",
  AppMethod.DELETE: "delete",
  AppMethod.PUT: "put"
};

class DioManager {
  static final DioManager _shared = DioManager._internal();
  factory DioManager() => _shared;
  Dio dio;

  DioManager._internal() {
    if (dio == null) {
      BaseOptions options = BaseOptions(
        baseUrl: AppApi.baseApi,
        contentType: Headers.jsonContentType,
        responseType: ResponseType.json,
        receiveDataWhenStatusError: false,
        connectTimeout: 60000,
        receiveTimeout: 3000,
      );
      dio = Dio(options);
      dio.interceptors.add(PrettyDioLogger(
          requestHeader: true,
          requestBody: true,
          responseBody: true,
          responseHeader: false,
          error: true,
          compact: true,
          maxWidth: 120));
    }
  }

  /// 请求，返回参数为 T
  /// method：请求方法，AppMethod.POST等
  /// path：请求地址
  /// params：请求参数
  /// success：请求成功回调
  /// error：请求失败回调
  Future request<T>(AppMethod method, String path,
      {Map<String, dynamic> params,
      bool showLoading = true,
      Function(BaseEntity) success,
      Function(ErrorEntity) error}) async {
    try {
      // String token = SpUtil.getString('token');
      // if (token != null) {
      //   dio.options.headers['token'] = token;
      // }
      Response response = await dio.request(path,
          queryParameters: params,
          options: Options(method: AppMethodValues[method]));

      if (response != null) {
        BaseEntity entity;
        try {
          entity = BaseEntity<T>.fromJson(jsonDecode(response.data));
        } catch (e) {
          entity = BaseEntity.fromJson(
              {'status': response.data['status'], 'msg': response.data['msg']});
          print(e);
        }
        if (entity.status == successCode) {
          success(entity);
        } else if (entity.status == tokenFailureCode) {
          // showMsg('token失效，请重新登录');
          // EasyLoading.dismiss();
          // // Navigator.of(getGlobalContext()).pushAndRemoveUntil(
          // //     FadeRoute(page: AppRoutes.hom), (route) => route == null);
          // NavigatorUtils.loginPage();
        } else {
          error(ErrorEntity(status: entity.status, msg: entity.msg));
        }
      } else {
        error(ErrorEntity(status: -1, msg: "未知错误"));
      }
    } on DioError catch (e) {
      error(createErrorEntity(e));
    }
  }

  /// 请求，返回参数为 List
  /// method：请求方法，AppMethod.POST等
  /// path：请求地址
  /// params：请求参数
  /// success：请求成功回调
  /// error：请求失败回调
  // Future requestList<T>(AppMethod method, String path,
  //     {Map<String, dynamic> params,
  //     Function(BaseListEntity response) success,
  //     Function(ErrorEntity) error}) async {
  //   try {
  //     Response response = await dio.request(path,
  //         queryParameters: params,
  //         options: Options(method: AppMethodValues[method]));
  //     if (response != null) {
  //       BaseListEntity entity =
  //           BaseListEntity<T>.fromJson(jsonDecode(response.data));
  //       if (entity.status == successCode) {
  //         success(entity);
  //       } else if (entity.status == tokenFailureCode) {
  //         showMsg('token失效，请重新登录');
  //         NavigatorUtils.loginPage();
  //       } else {
  //         error(ErrorEntity(status: entity.status, msg: entity.msg));
  //       }
  //     } else {
  //       error(ErrorEntity(status: -1, msg: "未知错误"));
  //     }
  //   } on DioError catch (e) {
  //     error(createErrorEntity(e));
  //   }
  // }

  /// 上传文件，返回参数为 T
  /// path:请求地址
  /// filePath: 文件路径
  /// params：请求参数
  /// success：请求成功回调
  /// error：请求失败回调
  Future uploadFile<T>(String path, String filePath,
      {Map<String, dynamic> params,
      Function(T) success,
      Function(ErrorEntity) error}) async {
    try {
      ///通过FormData

      Map<String, dynamic> map = Map();
      String fileName = filePath.split('.').last;
      map["file"] = await MultipartFile.fromFile(filePath,
          filename: "${DateTime.now().toString()}.$fileName");
      FormData formData = FormData.fromMap(map);
      String token = SpUtil.getString('token');
      if (token != null) {
        dio.options.headers['token'] = token;
      }
      // EasyLoading.showProgress(0, status: '上传中...');

      Response response = await dio.post(
        path,
        data: formData,
        onSendProgress: (int progress, int total) {
          print("当前进度是 $progress 总进度是 $total");
          // EasyLoading.showProgress(progress / total, status: '上传中...');
          // if (progress == total) {
          //   EasyLoading.dismiss();
          // }
        },
      );

      if (response != null) {
        BaseEntity entity;
        try {
          entity = BaseEntity<T>.fromJson(jsonDecode(response.data));
        } catch (e) {
          entity = BaseEntity.fromJson(
              {'status': response.data['status'], 'msg': response.data['msg']});
          print(e);
        }
        // EasyLoading.dismiss();
        // BaseEntity entity = BaseEntity<T>.fromJson(jsonDecode(response.data));
        if (entity.status == successCode) {
          success(entity.data);
        } else if (entity.status == tokenFailureCode) {
          // showMsg('token失效，请重新登录');
        } else {
          error(ErrorEntity(status: entity.status, msg: entity.msg));
        }
      } else {
        error(ErrorEntity(status: -1, msg: "未知错误"));
      }
    } on DioError catch (e) {
      error(createErrorEntity(e));
    }
  }

  ///下载文件，返回参数为 T
  /// path:请求地址
  /// savePath: 保存文件路径
  /// params：请求参数
  /// success：请求成功回调
  /// error：请求失败回调
  Future downloadFile<T>(String path, String savePath,
      {Map<String, dynamic> params,
      Function(double per) progress,
      Function() success,
      Function(ErrorEntity) error}) async {
    try {
      Response response = await dio.download(
        path,
        savePath,
        queryParameters: params,
        onReceiveProgress: (int progress, int total) {
          // print("当前进度是 $progress 总进度是 $total");
        },
      );
      if (response != null) {
        success();
      } else {
        error(ErrorEntity(status: -1, msg: "未知错误"));
      }
    } on DioError catch (e) {
      error(createErrorEntity(e));
    }
  }

  /// 错误信息
  ErrorEntity createErrorEntity(DioError error) {
    switch (error.type) {
      case DioErrorType.CANCEL:
        {
          return ErrorEntity(status: -1, msg: "请求取消");
        }
        break;
      case DioErrorType.CONNECT_TIMEOUT:
        {
          return ErrorEntity(status: -1, msg: "连接超时");
        }
        break;
      case DioErrorType.SEND_TIMEOUT:
        {
          return ErrorEntity(status: -1, msg: "请求超时");
        }
        break;
      case DioErrorType.RECEIVE_TIMEOUT:
        {
          return ErrorEntity(status: -1, msg: "响应超时");
        }
        break;
      case DioErrorType.RESPONSE:
        {
          try {
            int errCode = error.response.statusCode;
            String errMsg = error.response.statusMessage;
            return ErrorEntity(status: errCode, msg: errMsg);
//     switch (errCode) {
//      case 400: {
//       return ErrorEntity(code: errCode, msg: "请求语法错误");
//      }
//      break;
//      case 403: {
//       return ErrorEntity(code: errCode, msg: "服务器拒绝执行");
//      }
//      break;
//      case 404: {
//       return ErrorEntity(code: errCode, msg: "无法连接服务器");
//      }
//      break;
//      case 405: {
//       return ErrorEntity(code: errCode, msg: "请求方法被禁止");
//      }
//      break;
//      case 500: {
//       return ErrorEntity(code: errCode, msg: "服务器内部错误");
//      }
//      break;
//      case 502: {
//       return ErrorEntity(code: errCode, msg: "无效的请求");
//      }
//      break;
//      case 503: {
//       return ErrorEntity(code: errCode, msg: "服务器挂了");
//      }
//      break;
//      case 505: {
//       return ErrorEntity(code: errCode, msg: "不支持HTTP协议请求");
//      }
//      break;
//      default: {
//       return ErrorEntity(code: errCode, msg: "未知错误");
//      }
//     }
          } on Exception catch (_) {
            return ErrorEntity(status: -1, msg: "未知错误");
          }
        }
        break;
      default:
        {
          return ErrorEntity(status: -1, msg: error.response.statusMessage);
        }
    }
  }
}
